home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.3 Development Libraries / SGI IRIX 6.3 Development Libraries.iso / dist6.3 / gl_dev.idb / usr / share / src / OpenGL / teach / xlib / mouse.c.z / mouse.c
Encoding:
C/C++ Source or Header  |  1996-12-06  |  4.2 KB  |  191 lines

  1. /*
  2.  * mouse - double buffered RGBA xlib program which uses mouse motion events.
  3.  */
  4. /* compile: cc -o mouse mouse.c -lGLU -lGL -lX11 */
  5.  
  6. #include <GL/glx.h>
  7. #include <GL/glu.h>
  8. #include <X11/keysym.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11.  
  12. static int attributeList[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_DOUBLEBUFFER, None };
  13.  
  14. GLfloat trans[3];    /* current translation */
  15. GLfloat rot[2];        /* current rotation */
  16.  
  17. static void
  18. initialize(void) {
  19.     glShadeModel(GL_FLAT);
  20.     gluPerspective(40., 3.0/2.0, 0.001, 100000.0);
  21.     glTranslatef(0.0, 0.0, -3.0);
  22.     glClearColor(0.2,0.2,0.2,0.);
  23. }
  24.  
  25. static void
  26. side(void) { /* make a square translated 0.5 in the z direction */
  27.     glPushMatrix();
  28.     glTranslatef(0.0,0.0,0.5);
  29.     glRectf(-0.5,-0.5,0.5,0.5);
  30.     glPopMatrix();
  31. }
  32.  
  33. static void
  34. cube(void) { /* make a cube out of 4 squares */
  35.     glPushMatrix();
  36.     side();
  37.     glRotatef(90.,1.,0.,0.);
  38.     side();
  39.     glRotatef(90.,1.,0.,0.);
  40.     side();
  41.     glRotatef(90.,1.,0.,0.);
  42.     side();
  43.     glPopMatrix();
  44. }
  45.  
  46. static void
  47. draw_scene(void) {
  48.  
  49.     glClear(GL_COLOR_BUFFER_BIT);
  50.     glPushMatrix();
  51.     glTranslatef(trans[0], trans[1], trans[2]);
  52.     glRotatef(rot[0], 1.0, 0.0, 0.0);
  53.     glRotatef(rot[1], 0.0, 1.0, 0.0);
  54.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  55.     glColor3f(.1, .1, .8);
  56.     cube();
  57.     glScalef(0.3,0.3,0.3);
  58.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  59.     glColor3f(.8, .8, .1);
  60.     cube();
  61.     glPopMatrix();
  62. }
  63.  
  64. static void
  65. update_view(int mstate, int ox, int nx, int oy, int ny) {
  66.     int dx = ox - nx;
  67.     int dy = ny - oy;
  68.  
  69.     switch(mstate) {
  70.     case 1:    /* pan */
  71.     trans[0] -= dx/100.;
  72.     trans[1] -= dy/100.;
  73.     break;
  74.     case 2:    /* rotate */
  75.     rot[0] += (dy * 180.0)/500.;
  76.     rot[1] -= (dx * 180.0)/500.;
  77. #define clamp(x) x = x > 360. ? x-360. : x < -360. ? x += 360. : x 
  78.     clamp(rot[0]);
  79.     clamp(rot[1]);
  80.     break;
  81.     case 3:    /* zoom */
  82.     trans[2] -= (dx+dy)/100.;
  83.     break;
  84.     }
  85. }
  86.  
  87. static int
  88. process_input(Display *dpy) {
  89.     XEvent event;
  90.     Bool redraw = 0;
  91.     static int mstate, omx, omy, mx, my;
  92.  
  93.     do {
  94.     char buf[31];
  95.     KeySym keysym;
  96.  
  97.     XNextEvent(dpy, &event);
  98.     switch(event.type) {
  99.     case Expose:
  100.         redraw = 1;
  101.         break;
  102.     case ConfigureNotify:
  103.         glViewport(0, 0, event.xconfigure.width, event.xconfigure.height);
  104.         redraw = 1;
  105.         break;
  106.     case KeyPress:
  107.         (void) XLookupString(&event.xkey, buf, sizeof(buf), &keysym, NULL);
  108.         switch (keysym) {
  109.         case XK_Escape:
  110.         exit(EXIT_SUCCESS);
  111.         default:
  112.         break;
  113.         }
  114.     case ButtonPress:
  115.         if (event.xbutton.button == Button2) {
  116.         mstate |= 2;
  117.         mx = event.xbutton.x;
  118.         my = event.xbutton.y;
  119.         } else if (event.xbutton.button == Button1) {
  120.         mstate |= 1;
  121.         mx = event.xbutton.x;
  122.         my = event.xbutton.y;
  123.         }
  124.         break;
  125.     case ButtonRelease:
  126.         if (event.xbutton.button == Button2)
  127.         mstate &= ~2;
  128.         else if (event.xbutton.button == Button1)
  129.         mstate &= ~1;
  130.         break;
  131.     case MotionNotify:
  132.         if (mstate) {
  133.         omx = mx;
  134.         omy = my;
  135.         mx = event.xbutton.x;
  136.         my = event.xbutton.y;
  137.         update_view(mstate, omx,mx,omy,my);
  138.         redraw = 1;
  139.         }
  140.         break;
  141.     default:
  142.         break;
  143.     }
  144.     } while (XPending(dpy));
  145.     return redraw;
  146. }
  147.  
  148. int
  149. main(int argc, char **argv) {
  150.     Display *dpy;
  151.     XVisualInfo *vi;
  152.     XSetWindowAttributes swa;
  153.     Window win;
  154.     GLXContext cx;
  155.     Bool isdirect;
  156.  
  157.     dpy = XOpenDisplay(0);
  158.  
  159.     if (!(vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList))) {
  160.     fprintf(stderr, "mouse: no suitable RGB visual available\n");
  161.     exit(EXIT_FAILURE);
  162.     }
  163.  
  164.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  165.     isdirect = glXIsDirect(dpy, cx);
  166.  
  167.     swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
  168.                                    vi->visual, AllocNone);
  169.  
  170.     swa.border_pixel = 0;
  171.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask |
  172.     ButtonPressMask | ButtonReleaseMask | ButtonMotionMask ;
  173.     win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 300, 300,
  174.             0, vi->depth, InputOutput, vi->visual,
  175.             CWBorderPixel|CWColormap|CWEventMask, &swa);
  176.     XStoreName(dpy, win, "mouse");
  177.     XMapWindow(dpy, win);
  178.  
  179.     glXMakeCurrent(dpy, win, cx);
  180.  
  181.     initialize();
  182.  
  183.     while (1) {
  184.     if (process_input(dpy)) {
  185.         draw_scene();
  186.         glXSwapBuffers(dpy, win);
  187.         if (!isdirect) glFinish();
  188.     }
  189.     }
  190. }
  191.